package com.qys.livesMall.financial.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qys.livesMall.common.constants.Constants;
import com.qys.livesMall.common.exception.QysException;
import com.qys.livesMall.financial.mapper.FinancialOnlineDetailMapper;
import com.qys.livesMall.financial.mapper.FinancialOnlineMapper;
import com.qys.livesMall.financial.model.dto.app.AppFinancialOnlineDetailPageDTO;
import com.qys.livesMall.financial.model.dto.app.AppFinancialOnlineUserPageDTO;
import com.qys.livesMall.financial.model.entity.FinancialOnline;
import com.qys.livesMall.financial.model.entity.FinancialOnlineDetail;
import com.qys.livesMall.financial.model.entity.FinancialOnlineUser;
import com.qys.livesMall.financial.mapper.FinancialOnlineUserMapper;
import com.qys.livesMall.financial.model.vo.app.AppFinancialOnlineDetailPageVO;
import com.qys.livesMall.financial.model.vo.app.AppFinancialOnlinePageVO;
import com.qys.livesMall.financial.model.vo.app.AppFinancialOnlineUserPageVO;
import com.qys.livesMall.financial.model.vo.app.child.AppOnlineFinancialUserIncomeVO;
import com.qys.livesMall.financial.service.FinancialOnlineService;
import com.qys.livesMall.financial.service.FinancialOnlineUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qys.livesMall.framework.utils.SecurityUtils;
import com.qys.livesMall.framework.view.BaseQuery;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户每日理财收益 服务实现类
 * </p>
 *
 * @author
 * @since 2023-06-13
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class FinancialOnlineUserServiceImpl extends ServiceImpl<FinancialOnlineUserMapper, FinancialOnlineUser> implements FinancialOnlineUserService {


    private final FinancialOnlineDetailMapper financialOnlineDetailMapper;
    private final FinancialOnlineMapper financialOnlineMapper;

    @Override
    public void generateUserIncome( FinancialOnlineDetail record) {
        LocalDate now = LocalDate.now();
        BigDecimal interestRate = null == record.getInterestRate() ? BigDecimal.ZERO : record.getInterestRate();
        List<FinancialOnlineUser> records=new ArrayList<>();
        for (int i = 0; i < record.getPeriod(); i++) {
            now=now.plusDays(1);
            FinancialOnlineUser userIncome = new FinancialOnlineUser();
            userIncome.setUserId(SecurityUtils.getUserId());
            userIncome.setFinancialOrderId(record.getId());
            userIncome.setIncomeDate(now);
            userIncome.setAmount(record.getAmount().multiply(interestRate));
            userIncome.setSettlementStatus(Constants.YesNoInt.NO);
            //添加到数据库
            records.add(userIncome);
        }
        this.saveBatch(records);
    }

    @Override
    public Page<AppFinancialOnlineUserPageVO> onlineUserPage(AppFinancialOnlineUserPageDTO pageDTO) {
        pageDTO.setUserId(SecurityUtils.getUserId());
        Page<AppFinancialOnlineUserPageVO> page = new Page<>(pageDTO.getPageNum(), pageDTO.getPageSize());
        page=financialOnlineDetailMapper.onlineUserPage(page, pageDTO);
        if (CollectionUtils.isNotEmpty(page.getRecords())) {
            List<AppFinancialOnlineUserPageVO> voList = new ArrayList<>();
            List<Long> ids=page.getRecords().stream().map(AppFinancialOnlineUserPageVO::getId).collect(Collectors.toList());
            LambdaQueryWrapper<FinancialOnline> queryWrapper=new LambdaQueryWrapper<>();
            queryWrapper.in(FinancialOnline::getId,ids);
            List<FinancialOnline> financialOnlines=financialOnlineMapper.selectList(queryWrapper);
            Map<Long,FinancialOnline> financialOnlineMap=financialOnlines.stream().collect(Collectors.toMap(FinancialOnline::getId,a->a,(value1,value2)->value2));
            for (AppFinancialOnlineUserPageVO record : page.getRecords()) {
                FinancialOnline financial =financialOnlineMap.get(record.getId());
                record.setTotalRevenue(
                (record.getTotalRevenue()==null||record.getTotalRevenue().compareTo(BigDecimal.ZERO)==0)?
                        financial.getInterestRate().multiply(financial.getMaxAmount()).multiply(BigDecimal.valueOf(financial.getPeriod())):record.getTotalRevenue());
                BigDecimal amount = baseMapper.sumAmountByUserIdAndFinancialId(SecurityUtils.getUserId(), Arrays.asList(record.getZid()) );
                record.setIncome(amount);
                voList.add(record);
            }

            page.setRecords(voList);
        }
        return page;
    }

    @Override
    public AppFinancialOnlineUserPageVO getByFinancialId(Long financialId) {
        FinancialOnline financial = financialOnlineMapper.selectById(financialId);
        if (null == financial) {
            throw new QysException("请检查ID");
        }
        //产品信息
        AppFinancialOnlineUserPageVO vo = setFinancialInfo(financialId, financial.getPeriod());
        vo.setName(financial.getName());
        vo.setPeriod(financial.getPeriod());
        vo.setTotalRevenue(
                (vo.getTotalRevenue()==null||vo.getTotalRevenue().compareTo(BigDecimal.ZERO)==0)?
                financial.getInterestRate().multiply(financial.getMaxAmount()).multiply(BigDecimal.valueOf(financial.getPeriod())):vo.getTotalRevenue());
        vo.setAmount((vo.getAmount()==null||vo.getAmount().compareTo(BigDecimal.ZERO)==0)?financial.getMaxAmount():vo.getAmount());

        vo.setInterestRate(financial.getInterestRate());
        LambdaQueryWrapper<FinancialOnlineDetail> wrapper = Wrappers.<FinancialOnlineDetail>lambdaQuery()
                .eq(FinancialOnlineDetail::getOnlineFinancialId,financialId);
        wrapper.eq(FinancialOnlineDetail::getUserId, SecurityUtils.getUserId()).last("limit 1");
        FinancialOnlineDetail one = financialOnlineDetailMapper.selectOne(wrapper);
        vo.setBuyFlag(null != one);
        //收益明细
        List<AppOnlineFinancialUserIncomeVO> userIncomeVOS = setIncomeDetail(financialId, financial.getInterestRate(), vo);
        userIncomeVOS= userIncomeVOS.stream().sorted(Comparator.comparing(AppOnlineFinancialUserIncomeVO::getDate)).collect(Collectors.toList());
        vo.setUserIncomeVOS(userIncomeVOS);
        return vo;
    }

    /**
     * 设置产品信息
     *
     * @param financialId
     * @param period
     * @return
     */
    private AppFinancialOnlineUserPageVO setFinancialInfo(Long financialId, Integer period) {
        AppFinancialOnlineUserPageVO vo = new AppFinancialOnlineUserPageVO();
        vo.setDay(period);

        List<FinancialOnlineDetail> financialOnlineDetails = financialOnlineDetailMapper.sumAmountByUserIdAndFinancialId(SecurityUtils.getUserId(), financialId);
        if (CollectionUtils.isNotEmpty(financialOnlineDetails)){
            BigDecimal amount=financialOnlineDetails.stream().map(FinancialOnlineDetail::getAmount).reduce(BigDecimal.ZERO,BigDecimal::add);
            vo.setAmount(amount);
            List<Long> ids=financialOnlineDetails.stream().map(FinancialOnlineDetail::getId).collect(Collectors.toList());
            amount= baseMapper.sumAmountByUserIdAndFinancialId(SecurityUtils.getUserId(), ids);
            vo.setTotalRevenue(amount);
        }
        List<FinancialOnlineDetail> records = financialOnlineDetailMapper.selectList(Wrappers.<FinancialOnlineDetail>lambdaQuery()
                .eq(FinancialOnlineDetail::getUserId, SecurityUtils.getUserId())
                .eq(FinancialOnlineDetail::getOnlineFinancialId, financialId)
        );
        if (CollectionUtils.isNotEmpty(records)) {
            vo.setContract(records.get(0).getContract());
        }
        return vo;
    }


    /**
     * 获取收益明细
     *
     * @param financialId
     * @param ratio
     * @param financialVO
     */
    private List<AppOnlineFinancialUserIncomeVO> setIncomeDetail(Long financialId, BigDecimal ratio, AppFinancialOnlineUserPageVO financialVO) {
        LambdaQueryWrapper<FinancialOnlineUser> wrapper = Wrappers.<FinancialOnlineUser>lambdaQuery()
                .eq(FinancialOnlineUser::getUserId, SecurityUtils.getUserId())
//                .eq(FinancialOnlineUser::getFinancialId, financialId)
                .orderByDesc(FinancialOnlineUser::getIncomeDate);
        List<FinancialOnlineUser> userIncomeList = baseMapper.selectList(wrapper);

        List<AppOnlineFinancialUserIncomeVO> userIncomeVOS = new ArrayList<>(userIncomeList.size());
        //根据日期分组
        Map<LocalDate, List<FinancialOnlineUser>> collect = userIncomeList.stream().collect(Collectors.groupingBy(FinancialOnlineUser::getIncomeDate));
        collect.forEach((date, incomes) -> {

            AppOnlineFinancialUserIncomeVO vo = new AppOnlineFinancialUserIncomeVO();
            vo.setDate(date);
            vo.setPercent(ratio);
            vo.setInput(financialVO.getAmount());

            BigDecimal amount = BigDecimal.ZERO;
            for (FinancialOnlineUser income : incomes) {
                amount = amount.add(income.getAmount());
            }
            vo.setIncome(amount);

            userIncomeVOS.add(vo);
        });

        return userIncomeVOS;
    }

}
